'''

A registry of sorts for Butler's components to store data.

'''

import inspect  #For stack inspection


class RegistryEntry:
    name = None
    value = None
    creator = None

    def __init__(self, myentry=None):
        '''Creates a registry entry from a tuple if possible.'''
        if myentry:
            try:
                n, v, c = eval(myentry)
                self.name = n
                self.value = v
                self.creator = c
            except:
                print("Couldn't parse registry entry: %s" % (myentry))
                pass

    def dump(self):
        '''Returns a string representation of the entry.'''
        value = str(self.value)
        if isinstance(self.value, str):
            value = "'%s'" % self.value

        return "('%s', %s, '%s')" % (self.name, value, self.creator)



class Registry:

    registry = []

    def __init__(self, restore_path=None):
        '''Creates a new registry, if restore_path is set to a filepath
        the registry is restored from the given file.
        '''
        if restore_path:
            with open(restore_path) as f:
                for line in f:
                    r = RegistryEntry(line)
                    self.registry.append(r)



    def store(self, key, value):
        '''
        Stores a value to the registry with the key given. If the
        key exists it will be overwritten, if the key given doesn't
        belong to the calling object changes will not be written.

        returns true on success.
        '''
        #Primitive access control.
        frm = inspect.stack()[1]
        mod = inspect.getmodule(frm[0])
        caller = mod.__name__

        for entry in self.registry:
            if key == entry.name:
                if caller == entry.creator or entry.creator == "":
                    entry.value = value
                    return True
                else:
                    print "Warning: Access restriction violation attempt %s" % (name)
                    return False

        #Key must not have been in registry, create a new one.
        r = RegistryEntry()
        r.name = key
        r.value = value
        r.creator = caller

        self.registry.append(r)
        return True

    def dump(self):
        '''Returns a string representation of the registry.'''
        d = ""

        for r in self.registry:
            d += r.dump() + "\n"

        return d

    def dump_to_file(self, filepath):
        '''Dumps the registry to the file given if possible.'''
        with open(filepath, 'w') as f:
            f.write(self.dump())

    def fetch(self, key, default=None):
        '''Fetches a value from the registry, returns default if not
        found.
        '''
        for entry in self.registry:
            if entry.name == key:
                return entry.value
        return default